package edu.usc.csci578.algorithm;

import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.*;

import edu.usc.csci578.algorithm.*;
import edu.usc.csci578.manager.AlgorithmManager;
import edu.usc.csci578.model.*;

public class ConnectorEnvyAlgorithm extends AbstracAlgorithm
{
	public String NAME="ConnectorEnvyAlgorithm";
	public String DESCRIPTION="Detect the connector envy architecture smell in software architecture. An connector envy smell is when component partly involves the responsiblity of a connector";

	private double threshold = 0.2;
	
	public ConnectorEnvyAlgorithm()
	{
		AlgorithmManager.getInstance().registerAlgorithm(this);
	}
	@Override
	public SolutionSet execute(OutputStream stream) throws Exception
	{
		SolutionSet sols = new SolutionSet();
		PrintWriter out = new PrintWriter(stream);
		boolean Spec;
		int count = 0;
		out.println("Connector Envy Detec Algorithm Started");
		
		Map<String,Integer> words = new HashMap<String,Integer>();
		
		for(STopic topic:mm.getAllTopics())
		{
			int amend = topic.isSpec()?1:-1;
			for(String word:topic.getWords())
			{
				if(words.containsKey(word))
					words.put(word, words.get(word)+amend);
				else
					words.put(word, amend);
			}
		}
		
		for(Cluster cluster:mm.getAllClusters())
		{
			Spec = cluster.isSpec();
			CheckLoop:
			for(STopic topic:cluster.getTopics())
			{
				if((topic.isSpec()!=Spec)&&(cluster.getProbablity(topic)>=threshold))
				{
					Solution sol = new Solution();
					sol.add(cluster);
					sols.add(sol);
					count++;
					out.println("Connector Envy found : "+cluster.getName());
					break CheckLoop;
				}
				else
				{
					for(SClass aclass : cluster.getClasses())
						for(SMethod method : aclass.getMethods())
						{
							String name = method.getUniqueName();
							name.replaceFirst("org.apache.oodt.cas.filemgr", "");
							int accumulent=0;
							for(String word: words.keySet())
								if(name.indexOf(word)>=0)
									accumulent+=words.get(word);
							if((accumulent>0)!=Spec)
							{
								Solution sol = new Solution();
								sol.add(cluster);
								sols.add(sol);
								count++;
								out.println("Connector Envy found : "+cluster.getName());
								break CheckLoop;
							}
						}
				}
			}
		}

		//
				
		out.println("Connector Envy Found Total : "+count);
		out.println("Connector Envy Detec Algorithm Stopped.");
		out.flush();
		
		return sols;
	}
	
	public static void main(String[] args)
	{
		System.out.println("True ^ True = "+((true^true)?"True":"False") );
		System.out.println("True ^ False = "+((true^false)?"True":"False") );
	}
	@Override
	public String getDescription()
	{
		return this.DESCRIPTION;
	}
	@Override
	public String getName()
	{
		return this.NAME;
	}

}
